package components;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;

public class JDErrorDialog extends JDialog{

	private static final long serialVersionUID = 1L;

	private JButton btnOk;
	private JButton btnDetalhes;
	private JPanel panelBotoes;

	private boolean comDetalhes = false;

	private JPanel panel;
	private JPanel panelNorth;
	//private JButton btnEnviarPorEmail;
	private JLabel lblMensagem;
	private Dimension originalDimension = null;

	private JScrollPane scrollPilha;
	private JTextArea textAreaPilha;
	private JPanel panelPilha;
	private JPanel panelMensagensPilha;
	private JComponent parent;

	/**
	 * Create the dialog.
	 */
	private JDErrorDialog() {
		this(null);
	}
	
	private JDErrorDialog(JComponent parent) {
		this.parent = parent;
		init();
	}

	private void init() {
		this.setModal(true);
		setTitle("Attention"); //$NON-NLS-1$
		getContentPane().setLayout(new BorderLayout(0, 0));
		//this.setIconImage(new ImageIcon(getClass().getResource("/images/logoCoop.gif")).getImage());

		panel = new JPanel();
		getContentPane().add(panel, BorderLayout.CENTER);
		panel.setLayout(new BorderLayout(0, 0));

		panelNorth = new JPanel();
		panel.add(panelNorth, BorderLayout.NORTH);
		panelNorth.setLayout(new BorderLayout());
		panelNorth.setBorder(new EmptyBorder(15, 15, 15, 15));

		lblMensagem = new JLabel();
		panelNorth.add(lblMensagem);

		panelMensagensPilha = new JPanel();
		panel.add(panelMensagensPilha, BorderLayout.CENTER);
		panelMensagensPilha.setLayout(new GridLayout(0, 1, 0, 0));
		panelPilha = new JPanel();
		panelMensagensPilha.add(panelPilha);
		panelPilha.setLayout(new BorderLayout());

		textAreaPilha = new JTextArea();
		textAreaPilha.setFont(textAreaPilha.getFont().deriveFont(10f));
		textAreaPilha.setEditable(false);

		scrollPilha = new JScrollPane(textAreaPilha);

		panelPilha.add(scrollPilha);

		panelPilha.setFocusable(false);

		MouseAdapter mouseAdapter = new MouseAdapter() {
			@Override
			public void mouseReleased(MouseEvent e) {
				if (e.getButton() == MouseEvent.BUTTON2 || e.getButton() == MouseEvent.BUTTON3) {
						JPopupMenu popup = createPopupMenu();
						popup.show(e.getComponent(), e.getX(), e.getY());
				}
			}

		};

		textAreaPilha.addMouseListener(mouseAdapter);
		lblMensagem.addMouseListener(mouseAdapter);

		panelBotoes = new JPanel();
		getContentPane().add(panelBotoes, BorderLayout.SOUTH);

		btnOk = new JButton();
		btnOk.setFocusable(true);
		btnOk.setText("Ok");
		btnOk.setMargin(new Insets(2, 20, 2, 20));
		btnOk.setMnemonic('O');
		btnOk.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				dispose();
			}
		});
		panelBotoes.add(btnOk);

//		btnEnviarPorEmail = new JButton();
//		btnEnviarPorEmail.setFocusable(true);
//		btnEnviarPorEmail.setText("Sent e-mail");
//		btnEnviarPorEmail.setMargin(new Insets(2, 20, 2, 20));
//		btnEnviarPorEmail.addActionListener(new ActionListener() {
//			@Override
//			public void actionPerformed(ActionEvent e) {
//				//enviarPorEmail();
//			}
//		});
//		btnEnviarPorEmail.setMnemonic('E');
//		btnEnviarPorEmail.setVisible(false);

		btnDetalhes = new JButton();
		btnDetalhes.setFocusable(true);
		btnDetalhes.setText("Details");
		btnDetalhes.setMargin(new Insets(2, 20, 2, 20));
		btnDetalhes.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				comDetalhes = !comDetalhes;
				hideOrShowDetail(comDetalhes);

			}
		});
		btnDetalhes.setMnemonic('D');
		panelBotoes.add(btnDetalhes);
//		btnEnviarPorEmail.setToolTipText("");
//		panelBotoes.add(btnEnviarPorEmail);

		//ClientUtil.registerEnterEventInButtons(panelBotoes);

		addWindowListener(new WindowAdapter() {
			@Override
			public void windowOpened(WindowEvent e) {
				btnOk.requestFocusInWindow();
			}
		});
		
	}

	public static void reportException(Throwable ex) {
		reportException(ex, null);
	}
	
	public static void reportException(Throwable ex, JComponent parent) {

		JDErrorDialog errorDialog = new JDErrorDialog(parent);
		
		ex.printStackTrace();
		
		errorDialog.doReport(ex);
	}

	/**
	 * M�todo chamado para reportar uma exce��o na tela
	 * 
	 * @param ex
	 */
	private void doReport(Throwable ex) {

		adicionarMensagem(ex);

		if (ex.getMessage() == null) {
			lblMensagem.setText(formataHmtl("Error"));
			//lblMensagem.setIcon(new ImageIcon(ErrorDialog.class.getResource("/images/fatalError.png")));
		} else {
			lblMensagem.setText(formataHmtl(ex.getMessage()));
			//lblMensagem.setIcon(new ImageIcon(ErrorDialog.class.getResource("/images/warning.png")));
		}

		comDetalhes = false;
		hideOrShowDetail(comDetalhes);

		this.pack();
		
		Dimension dimension = getSize();
		
		if(dimension.width > 800){
			dimension.width = 800;
			dimension.height = dimension.height + lblMensagem.getSize().height;
			setSize(dimension);
		}
		setMinimumSize(dimension);
		originalDimension = this.getSize();
		
		setLocationRelativeTo(parent);
		
		this.setVisible(true);
	}

	private String formataHmtl(String message) {
		String mess = "<html>";
		if (message != null) {
			mess += message.replaceAll("\\n", "<br>");
		}
		mess += "</html>";
		
		return mess;
	}

	/**
	 * Metodo que adiciona a mensagem de erro que esta na excecao
	 */
	private void adicionarMensagem(Throwable exception) {
		textAreaPilha.setText(toString(exception));
		textAreaPilha.setCaretPosition(0);
	}

	public static String toString(Throwable exception) {
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		PrintStream ps = new PrintStream(baos);
		exception.printStackTrace(ps);
		adicionarDetalhes(exception.getCause(), ps);

		return baos.toString();
	}

	/**
	 * metodo chamado recursivamente para adicionar excecoes da pilha na mensagem
	 * 
	 * @param cause
	 * @param ps
	 */
	private static void adicionarDetalhes(Throwable cause, PrintStream ps) {
		if (cause != null) {
			cause.printStackTrace(ps);
			adicionarDetalhes(cause.getCause(), ps);
		}
	}

	/**
	 * metodo chamado para exibir ou esconder a pilha de excecao
	 * 
	 * @param show
	 */
	private void hideOrShowDetail(boolean show) {
		/**
		 * Altera o texto do botao Detalhes
		 */
		btnDetalhes.setText(comDetalhes ? "Without details" : "Details");
		/**
		 * Se mostra os detalhes - exibe o panel de detalhes - seta o tamanho para
		 * 800 x 600
		 */
		if (show) {
			panelMensagensPilha.add(panelPilha);
			// panelPilha.setVisible(true);
			setSize(800, 600);
		}
		/**
		 * Caso contrario - esconde os detalhes - seta o tamanho para o tamanho
		 * original sem a pilha
		 */
		else {
			panelMensagensPilha.remove(panelPilha);
			// panelPilha.setVisible(false);
			if (originalDimension != null) {
				setSize(originalDimension);
			}
		}
		/**
		 * redesenho tela e posiciono ela no centro
		 */
		paintAll(getGraphics());
		repaint();
		setLocationRelativeTo(parent);
	}

	public static void main(String[] args) {

		/*
		 * DCMultiException dcMultiException = new DCMultiException();
		 * 
		 * dcMultiException.add(new Exception("ex1")); dcMultiException.add(new
		 * Exception("ex2")); dcMultiException.add(new Exception("ex3"));
		 * dcMultiException.add(new Exception("ex4")); dcMultiException.add(new
		 * Exception("ex5")); dcMultiException.add(new Exception("ex6"));
		 * dcMultiException.add(new Exception("ex7")); dcMultiException.add(new
		 * Exception("ex8")); dcMultiException.add(new Exception("ex19"));
		 * dcMultiException.add(new Exception("ex10")); dcMultiException.add(new
		 * Exception("ex11")); dcMultiException.add(new Exception("ex12"));
		 * dcMultiException.add(new Exception("ex13")); dcMultiException.add(new
		 * Exception("ex14")); dcMultiException.add(new Exception("ex15"));
		 * dcMultiException.add(new Exception("ex16")); dcMultiException.add(new
		 * Exception("ex17")); dcMultiException.add(new Exception("ex18"));
		 * dcMultiException.add(new Exception("ex19")); dcMultiException.add(new
		 * Exception("ex20")); dcMultiException.add(new Exception("ex21"));
		 * dcMultiException.add(new Exception("ex22")); dcMultiException.add(new
		 * Exception("ex23")); dcMultiException.add(new Exception("ex24"));
		 * dcMultiException.add(new Exception("ex25")); dcMultiException.add(new
		 * Exception("ex26")); dcMultiException.add(new Exception("ex27"));
		 * dcMultiException.add(new Exception("ex28")); dcMultiException.add(new
		 * Exception("ex29")); dcMultiException.add(new Exception("ex30"));
		 * dcMultiException.add(new Exception("ex31")); dcMultiException.add(new
		 * Exception("ex32")); dcMultiException.add(new Exception("ex33"));
		 * dcMultiException.add(new Exception("ex34")); dcMultiException.add(new
		 * Exception("ex35"));
		 */

		JDErrorDialog.reportException(new Exception("N�o foi encontrada  dsa dsa dasdsa das dsa das saConfigura��o de Op. Interna para o tipo de Faturamento, tipo de pedido e o tipo de cria��o informados."));

	}

	public JPopupMenu createPopupMenu() {
		JMenuItem menuItem;

		// Create the popup menu.
		JPopupMenu popup = new JPopupMenu();
		menuItem = new JMenuItem("  Copy  ");
		menuItem.setMnemonic('C');
		menuItem.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				copyTextArea();
			}
		});
		popup.add(menuItem);

		return popup;
	}

	private void copyTextArea() {
//		if (JUtil.isNullOrEmpty(textAreaPilha.getSelectedText())) {
//			ClientUtil.sendToClipboard(textAreaPilha.getText());
//		} else {
//			textAreaPilha.copy();
//		}
	}

}
